package com.lp.mgt.services.impls;

import static org.assertj.core.api.Assertions.contentOf;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.shiro.SecurityUtils;
import org.assertj.core.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lp.mgt.entities.Menu;
import com.lp.mgt.entities.Role;
import com.lp.mgt.entities.User;
import com.lp.mgt.mappers.UserMapper;
import com.lp.mgt.services.FileService;
import com.lp.mgt.services.MenuService;
import com.lp.mgt.services.PostService;
import com.lp.mgt.services.RoleService;
import com.lp.mgt.services.UserService;
import com.lp.mgt.utils.MD5Util;
import com.lp.mgt.utils.RandomUtil;
import com.lp.mgt.utils.ShrioUtil;
import com.lp.mgt.utils.UUIDUtil;
@Service
@Transactional
public class UserServiceImpl implements UserService {
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private FileService fileService;
	@Autowired
	private PostService postService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private RestTemplate restTemplate;
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	private JavaMailSender sender;
	@Value("${spring.mail.username}")
	private String from;
	
	
	
	
	@Override
	public User findUserById(String id) {
		User user= userMapper.findUserById(id);
		return user;
	}
	
	@Override
	public User findUserWithLogin(String name) {
		return userMapper.findUserByName(name);
	}
	
	//登录时shrioRealm中获取用户以及其头像，角色，权限信息
	@Override
	public User findUserByName(String name) {
		return userMapper.findUserByName(name);	
	}

	@Override
	public Integer saveUserWhenRegister(User user) {
		if(user!=null) {
			String id=UUIDUtil.getUUID();
			//SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :HH:mm:ss");
			user.setUid(id);
			user.setCreateTime(new Date());
			Calendar cal=Calendar.getInstance();
			cal.add(Calendar.DATE, 365*10);
			user.setExpireDate(cal.getTime());
			Map<String,String> map=MD5Util.encryption(user.getUsername(), user.getPassword()==null?user.getUsername():user.getPassword(), 2);
			user.setPassword(map.get("password"));
			user.setSalt(map.get("salt"));
			user.setState("1");
			user.setDelFlag("0");
			user.setCreateBy(ShrioUtil.getCurrentUser().getUid());
			userMapper.saveUserWhenRegister(user);
			//保存初始岗位
			if(user.getPostId()!=null&&!"".equals(user.getPostId())) {
				String[] pids=null;
				Map<String,Object> data=new HashMap<>();
				if(user.getPostId().indexOf(",")!=-1) {
					pids=user.getPostId().split(",");
				}else {
					pids=new String[]{user.getPostId()};
				}
				data.put("uid", user.getUid());
				data.put("pids", pids);
				userMapper.saveUserWithPost(data);//保存职位
			}
			//保存初始的角色
			if(user.getRoleIds()!=null&&!"".equals(user.getRoleIds())) {
				String[] rids=null;
				if(user.getRoleIds().indexOf(",")!=-1) {
					rids=user.getRoleIds().split(",");
					for(String rid:rids) {
						userMapper.saveRoleWhenRegisterUser(user.getUid(), rid);
					}
				}else {
					userMapper.saveRoleWhenRegisterUser(user.getUid(), user.getRoleIds());
				}
			}
			return 1;
		}else {
			return 0;
		}
	}

	@Override
	public HashMap<String, String> sendEmail(String username, String email) {
		ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
		HashMap<String, String> rt =new HashMap<>();
		String key=RandomUtil.getRandom(6)+"";
		//Timestamp outDate = new Timestamp(System.currentTimeMillis()+(long)(30*60*1000));//30分钟后过期          
        //long outTime=outDate.getTime()/ 1000 * 1000;//忽略毫秒数
		long outTime=30;
		//存入redis
        String sid=username+"&"+key+"&"+outTime;
        String digitalSignature = MD5Util.EncoderByMd5(sid);//数字签名
        ops.set(digitalSignature, key, outTime, TimeUnit.MINUTES);
        //邮件内容
        String emailTitle = "[综合管理系统]密码找回";
        //String path = request.getContextPath();
        String basePath ="http://localhost:8090/";
        String resetPassHref = basePath + "toResetPassword?sid=" + digitalSignature + "&username=" + username;
        String emailContent = "尊敬的"+username+"先生(女士)：<br/>你通过邮件方式发起了找回密码请求，<a href=" + resetPassHref + " target='_BLANK'>点击我重新设置密码</a></br> 若不能正常跳转，请复制URL("+resetPassHref+")到浏览器地址栏" +
                "<br/>tips:本邮件超过30分钟,链接将会失效，需要重新申请'找回密码'。请勿回复本邮件，如非本人操作请忽略此邮件！";
        System.out.print(resetPassHref);
        try {
			sendHtmlMail(emailContent, emailTitle,email);
		} catch (MessagingException e) {
			rt.put("msg", "邮件发送异常失败："+e.getMessage());
			rt.put("code", "er000");
			e.printStackTrace();
		}
        rt.put("msg", "密码重置邮件已发送，请尽快处理!");
        rt.put("code", "1000");
		return rt;
	}
	
	
    /**
     * 发送html格式的邮件
     *
     * @param to
     * @param subject
     * @param content
     * @throws MessagingException 
     */
    public void sendHtmlMail(String content, String subject, String to) throws MessagingException {
        MimeMessage message = sender.createMimeMessage();
            //true表示需要创建一个multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            sender.send(message);
            System.out.println("html邮件已发送");
    }

	@Override
	public Boolean getUserByNameWhenRegisterOrLogin(String username) {
		Integer count=userMapper.getUserByNameWhenRegisterOrLogin(username);
		return count==1?true:false;
	}

	@Override
	public Boolean checkUserWithNameAndEmail(String username, String email) {
		Integer count=userMapper.checkUserAndEmail(username,email);
		return count==1?true:false;
	}

	@Override
	public Boolean updateUserWithPassword(String username, String password) {
		Map<String,String> map=MD5Util.encryption(username,password, 2);
		User user=new User();
		user.setUsername(username);
		user.setPassword(map.get("password"));//密码加密
		//更新用户密码
		Integer n=userMapper.updateUserWithUsername(user);
		// TODO 自动生成的方法存根
		return n==1?true:false;
	}

	@Override
	public Map<String, Object> getUsersWithTerms(User user) {
		if("".equals(user.getState())||user.getState()==null) user.setState("2");
		Map<String,Object> map=new HashMap<>();
		Object count=null,datas=null;
		if(user.getPage()!=0&&user.getLimit()!=0) {
			PageHelper.startPage(user.getPage(), user.getLimit());
			List<User> list=userMapper.getUserDataWithTerms(user);
			PageInfo<User> pageInfo = new PageInfo<>(list);
			count=pageInfo.getTotal();
			datas=pageInfo.getList();
		}else {
			List<User> data=userMapper.getUserDataWithTerms(user);
			datas=data;
			count=data.size();
		}
		map.put("total",count);
		map.put("rows",datas);
		return map;
	}

	@Override
	public Map<String, Object> getOtherUserInfoById(String uid) {
		String str=userMapper.getOtherUserInfoById(uid);
		Map<String,Object> map=new HashMap<>();
		map.put("info", str);
		return map;
	}

	@Override
	public Boolean removeUserSingleOrBatch(String ids) {
		if("".equals(ids) ||ids==null) {
			return false;
		}
		String[] newIds = null;
		if(ids.indexOf("|")!=-1) {
			newIds=ids.split("\\|");
		}else {
			newIds=new String[] {ids};
		}
		HashMap<String,Object> map=new HashMap<>();
		map.put("arr", newIds);
		userMapper.removeUserSingleOrBatch(map);
		userMapper.removeUserAndRole(map);
		userMapper.removeUserAndFocus(map);
		userMapper.removeUserAndPost(map);
		return true;
	}

	@Override
	public Boolean updateUserWhenEdit(User user) {
		//先删除历史头像
		MultipartFile[] files=new MultipartFile[10];
		files[0]=user.getHeadPicture();
		if(files[0]!=null&&files[0].getSize()>0) {//重新选择了图片，大小才不为0.否则不重新上传
			Boolean flag=fileService.deleteAvatarFiles(user.getAid());
			String fileIds[]=fileService.avatarUpload(files,user.getUsername());//上传新头像
			String avatarId=fileIds[0]!=null?fileIds[0]:null;//关联头像id
			user.setAid(avatarId);
		}
		userMapper.updateUserWithUsername(user);//更新用户
		//删除岗位再新增
		postService.removePostByUserId(user.getUid());
		ShrioUtil.clearCachedAuthorizationInfo();//删除用户对应菜单权限,因为可能角色发生改变
		//在插入新岗位
		if(user.getPostId()!=null&&!"".equals(user.getPostId())) {
			//user.setPostId(user.getPostId().substring(0, user.getPostId().length() - 1));
			String[] pids=null;
			Map<String,Object> map=new HashMap<>();
			if(user.getPostId().indexOf(",")!=-1) {
				pids=user.getPostId().split(",");
			}else {
				pids=new String[]{user.getPostId()};
			}
			map.put("uid", user.getUid());
			map.put("pids", pids);
		userMapper.saveUserWithPost(map);
		}
		//删除角色
		HashMap<String,Object> map=new HashMap<>();
		map.put("arr",new String[] {user.getUid()});
		userMapper.removeUserAndRole(map);
		//新增角色
		if(user.getRoleIds()!=null&&!"".equals(user.getRoleIds())) {
			String[] rids=null;
			if(user.getRoleIds().indexOf(",")!=-1) {
				rids=user.getRoleIds().split(",");
				for(String rid:rids) {
					userMapper.saveRoleWhenRegisterUser(user.getUid(), rid);
				}
			}else {
				userMapper.saveRoleWhenRegisterUser(user.getUid(), user.getRoleIds());
			}
		}
		return true;
	}

	@Override
	public Map<String,Object> getUserWithoutRole(String roleId,String username,String page,String limit) {
		Map<String,Object> map=new HashMap<>();
		PageHelper.startPage(Integer.valueOf(page), Integer.valueOf(limit));
		List<User> list=userMapper.getUserWithoutRole(roleId,username);
		PageInfo<User> pageInfo = new PageInfo<>(list);
		map.put("total",pageInfo.getTotal());
		map.put("data", pageInfo.getList());
		System.out.println(pageInfo.getList());
		return map;
	}

	@Override
	public List<User> getUserWithRole(String roleId) {
		return userMapper.getUserWithRole(roleId);
	}

	@Override
	public Boolean divideUserWithRoleId(String type,String roleId, List<User> list) {
		String jsonStr=JSON.toJSONString(list);
		List<User> users=JSON.parseObject(jsonStr,new TypeReference<List<User>>(){});
		for(User user:users) {
			HashMap<String, String> map=new HashMap<>();
			map.put("uid", user.getUid());
			map.put("rid", roleId);
			if("add".equals(type)) {//新增
				int i=userMapper.addUserWithRole(map);
				if(i!=1) {
					return false;
				}
			}else {//删除
				int j=userMapper.deleteUserWithRoleIdAndUserId(map);
				if(j!=1) {
					return false;
				}
			}
		}
		return true;
	}

	@Override
	public Boolean effectiveOrinvalid(String ids, String type) {
		if(ids!=null) {
			String[] arr=null;
			if(ids.indexOf(",")!=-1) {
				arr=ids.split(",");
			}else {
				arr=new String[] {ids};
			}
			HashMap<String,Object> map=new HashMap<>();
			map.put("type", type);
			map.put("ids", arr);
			userMapper.effectiveOrinvalid(map);
			return true;
		}
		return false;
	}

	@Override
	public Boolean focusUser(String id, String type) {
		User currentUser=(User) SecurityUtils.getSubject().getPrincipal();
		String currId=currentUser.getUid();
		int rt=0;
		if("Y".equals(type)) {//关注插入关注表
			rt=userMapper.saveFocusUser(currId,id);
		}else {
			rt=userMapper.removeFocusUser(currId,id);
		}
		return rt==0?false:true;
	}

	@Override
	public Boolean removeUserByDeptId(String deptId) {
		userMapper.removeUserByDeptId(deptId);
		return true;
	}

}
